#include <mysql.h>
#include <stdarg.h>
//#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "diff.h"

#define DEBUG

typedef struct _SResult {
	char *buffer;
} SResult;

void udf_debug(char *msg, ...) {
#ifdef DEBUG
	va_list ap;

	va_start(ap, msg);
	vfprintf(stderr, msg, ap);
	va_end(ap);

	fflush(stderr);
#endif
}

my_bool diffUDF_init(UDF_INIT *initid, UDF_ARGS *args, char *message) {
	SResult *sresult;

	if (args->arg_count != 2 || args->arg_type[0] != STRING_RESULT
			|| args->arg_type[1] != STRING_RESULT) {
		strcpy(message, "diff() requires two strings arguments");
		return 1;
	}

	sresult = (SResult *) malloc(sizeof(SResult));
	sresult->buffer = 0;

	initid->max_length = 16 * 1024 * 1024;
	initid->maybe_null = 1;
	initid->ptr = (char *) sresult;

	return 0;
}

void diffUDF_deinit(UDF_INIT *initid) {
	SResult *sresult = (SResult *) initid->ptr;

	if (sresult->buffer != 0) {
		free(sresult->buffer);
		sresult->buffer = 0;
	}

	free(sresult);
}

char *diffUDF(UDF_INIT *initid, UDF_ARGS *args, char *result,
		unsigned long *length, char *is_null, char *error) {

	char *text1 = (char *) malloc(sizeof(char) * (args->lengths[0] + 1));
	char *text2 = (char *) malloc(sizeof(char) * (args->lengths[1] + 1));
	SResult *sresult = (SResult *) initid->ptr;

	strncpy(text1, args->args[0], args->lengths[0]);
	text1[args->lengths[0]] = 0;
	udf_debug(text1);
	udf_debug("\n");

	strncpy(text2, args->args[1], args->lengths[1]);
	text2[args->lengths[1]] = 0;
	udf_debug(text2);
	udf_debug("\n");

	diff(text1, text2, &(sresult->buffer));
	udf_debug(sresult->buffer);
	udf_debug("\n");

	*length = strlen(sresult->buffer);

	free(text1);
	free(text2);

	fflush(stderr);

	return sresult->buffer;
}
